package boardInfo

import (
	"bufio"
	"fmt"
	"os"
	"util"
)

const (
	FileZNZBoardHeadSize = 20
	BoardListItemSize    = 108
	BoardItemSize        = 34
)

type FileZNZBoardHead struct {
	DwCheck           uint32
	DwBoardCount      uint32
	DwMarketCodeCount uint32
	DwModifyDate      uint32
	DwModifyTime      uint32
}

func (head *FileZNZBoardHead) DeCode(b []byte) int {
	if len(b) < FileZNZBoardHeadSize {
		return 0
	}

	pos := 0
	bt := b[pos : pos+4]
	pos += 4
	head.DwCheck = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	head.DwBoardCount = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	head.DwMarketCodeCount = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	head.DwModifyDate = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	head.DwModifyTime = util.Byte2Base[uint32](bt)

	return FileZNZBoardHeadSize
}

type BoardListItem struct {
	DwBoardId    uint32
	DwPId        uint32
	SzBoardName  string //64
	DwStartDate  uint32
	DwEndDate    uint32
	DwModifyDate uint32
	DwModifyTime uint32
	DwBoardType  uint32
	DwLevelCode  uint32
	DwOrders     uint32
	DwDeleted    uint32
	FInitValue   float32
}

func (item *BoardListItem) DeCode(b []byte) int {
	if len(b) < BoardListItemSize {
		return 0
	}

	pos := 0
	bt := b[pos : pos+4]
	pos += 4
	item.DwBoardId = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	item.DwPId = util.Byte2Base[uint32](bt)

	const strNum = 64
	bt = b[pos : pos+strNum]
	pos += strNum
	num := btStrPos(bt)
	item.SzBoardName = string(bt[0:num])

	bt = b[pos : pos+4]
	pos += 4
	item.DwStartDate = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	item.DwEndDate = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	item.DwModifyDate = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	item.DwModifyTime = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	item.DwBoardType = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	item.DwLevelCode = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	item.DwOrders = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	item.DwDeleted = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	item.FInitValue = util.Byte2Base[float32](bt)

	return BoardListItemSize
}

type BoardItem struct {
	DwBoardId    uint32
	SzMarketCode string //14
	DwStartDate  uint32
	DwEndDate    uint32
	DwModifyDate uint32
	DwModifyTime uint32
}

func (item *BoardItem) DeCode(b []byte) int {
	if len(b) < BoardItemSize {
		return 0
	}

	pos := 0
	bt := b[pos : pos+4]
	pos += 4
	item.DwBoardId = util.Byte2Base[uint32](bt)

	const strNum = 14
	bt = b[pos : pos+strNum]
	pos += strNum
	num := btStrPos(bt)
	item.SzMarketCode = string(bt[0:num])

	bt = b[pos : pos+4]
	pos += 4
	item.DwStartDate = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	item.DwEndDate = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	item.DwModifyDate = util.Byte2Base[uint32](bt)

	bt = b[pos : pos+4]
	pos += 4
	item.DwModifyTime = util.Byte2Base[uint32](bt)

	return BoardItemSize
}

type StBoardInfo struct {
	Head      FileZNZBoardHead
	BListItem []*BoardListItem
	BItem     []*BoardItem
}

func (bi *StBoardInfo) writeToFile() {

	file, _ := os.Create("E:\\BoardInfo\\board_list_item.csv")
	writer := bufio.NewWriter(file)
	line := "DwBoardId, DwPId, SzBoardName, DwStartDate, DwEndDate, DwModifyDate, DwModifyTime, DwBoardType, DwLevelCode, DwOrders, DwDeleted, FInitValue\n"
	_, _ = writer.Write([]byte(line))

	for _, item := range bi.BListItem {

		line = fmt.Sprintf("%d, %d, %s, %d, %d, %d, %d, %d, %d, %d, %d, %f\n",
			item.DwBoardId, item.DwPId, item.SzBoardName, item.DwStartDate, item.DwEndDate, item.DwModifyDate,
			item.DwModifyTime, item.DwBoardType, item.DwLevelCode, item.DwOrders, item.DwDeleted, item.FInitValue)
		_, _ = writer.Write([]byte(line))
	}

	_ = file.Close()

	file, _ = os.Create("E:\\BoardInfo\\board_item.csv")
	writer = bufio.NewWriter(file)
	line = "DwBoardId, SzMarketCode, DwStartDate, DwEndDate, DwModifyDate, DwModifyTime\n"
	_, _ = writer.Write([]byte(line))

	for _, item := range bi.BItem {

		line = fmt.Sprintf("%d, %s, %d, %d, %d, %d\n",
			item.DwBoardId, item.SzMarketCode, item.DwStartDate, item.DwEndDate, item.DwModifyDate, item.DwModifyTime)
		_, _ = writer.Write([]byte(line))
	}
	_ = file.Close()
}

func handleBoardInfo(bt []byte, conn *stConnect) {
	res := &stResSmallFile{}
	err := res.DeCode(bt)
	if err != nil {
		return
	}

	bt = res.data
	boardInfo := &StBoardInfo{}
	num := boardInfo.Head.DeCode(bt)

	for idx := uint32(0); idx < boardInfo.Head.DwBoardCount; idx++ {
		bt = bt[num:]
		item := &BoardListItem{}
		num = item.DeCode(bt)
		if num == 0 {
			break
		}
		boardInfo.BListItem = append(boardInfo.BListItem, item)

	}

	for idx := uint32(0); idx < boardInfo.Head.DwMarketCodeCount; idx++ {
		bt = bt[num:]
		item := &BoardItem{}
		num = item.DeCode(bt)
		if num == 0 {
			break
		}
		boardInfo.BItem = append(boardInfo.BItem, item)
	}
	//boardInfo.writeToFile()
}

// 是必除股
func isMustRemove(boardId int) bool {
	return boardId == 2254 || boardId == 2266 || boardId == 2265
}

// 财务风险板块
func isFinancialRisk(boardId int) bool {
	return boardId == 2255 || boardId == 2268
}
